#include "mvc/view/airfoil_dialog.h"
#include "mvc/view/param_widget_uav.h"
#include "mvc/view/param_widget_conventional.h"
#include "ui_airfoil_dialog.h"
#include "common/settings.h"
#include <cmath>
#include <cstdlib>
#include <QDebug>
#include <QDesktopWidget>
#include <QMessageBox>
#include <QFile>
#include <iostream>
#include <QModelIndexList>
#include <QVector>
#include <QObject>
#include <QRegExp>

#include <QDir>
#include <QSortFilterProxyModel>

using std::cout;
using std::endl;

Airfoil_dialog::Airfoil_dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Airfoil_dialog)
{
    ui->setupUi(this);
    setModal(true);
    dirModel = new QFileSystemModel(this);
    retranslateUi();
    QSize windowsSize;
    windowsSize.setHeight(413);
    windowsSize.setWidth(700);
    this->setFixedSize(windowsSize);

    ui->listFiles->setModel(dirModel);

    QString d_airfoils = airfoils_directory();

    ui->listFiles->setRootIndex(dirModel->setRootPath(d_airfoils));
    ui->search_field_line->setFocus();
}

Airfoil_dialog::~Airfoil_dialog()
{
    delete ui;
}


/**
  * Return reference curve
  */

QVector<Point*> Airfoil_dialog::get_reference_curve()
{
    return reference_curve;
}

/**
  * Calculate the reference curve
  */
void Airfoil_dialog::calc_reference_curve(const QString &path)
{
    QVector<Point*> airfoil;

    load_reference_curve(path, airfoil);

    int sizeVector = airfoil.size();

    QVector<double> x(sizeVector), y(sizeVector);
    for (int i = 0; i < sizeVector; ++i)
    {
        x[i] = airfoil[i]->x;
        y[i] = airfoil[i]->y;
    }

    QVector<double> x_average(sizeVector / 2), y_average(sizeVector / 2);

    reference_curve.clear();
    reference_curve.resize(sizeVector / 2);

    for (int i = 0; i < sizeVector / 2; ++i)
    {
        x_average[i] = (x[i] + x[sizeVector - (i + 1)]) / 2;
        y_average[i] = (y[i] + y[sizeVector - (i + 1)]) / 2;

        reference_curve[i]  = new Point(x_average[i],y_average[i]);
    }
}

/**
  * Draw airfoil in the widget
  */
void Airfoil_dialog::drawAirfoil(QCustomPlot *customPlot, QString path)
{
    QVector<Point* > airfoil;

    load_reference_curve(path, airfoil);

    int sizeVector = airfoil.size();

    QVector<double> x(sizeVector), y(sizeVector);
    for (int i = 0; i < sizeVector; ++i)
    {
        x[i] = airfoil[i]->x;
        y[i] = airfoil[i]->y;
    }

    QVector<double> x_average(sizeVector / 2), y_average(sizeVector / 2);


    reference_curve.resize(sizeVector / 2);
    for (int i = 0; i < sizeVector / 2; ++i)
    {
        x_average[i] = (x[i] + x[sizeVector - (i + 1)]) / 2;
        y_average[i] = (y[i] + y[sizeVector - (i + 1)]) / 2;
        reference_curve[i] = new Point(x_average[i],  y_average[i]);
    }

//    customPlot->setInteraction(QCustomPlot::iSelectPlottables);
    QCPCurve *curve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);
    QCPCurve *curveAverage = new QCPCurve(customPlot->xAxis, customPlot->yAxis);

    customPlot->xAxis->setRange(0, 1);
    customPlot->yAxis->setRange(-0.25, 0.25);

    curve->setData(x, y);
    curve->setPen(QPen(Qt::blue));
    curve->setBrush(QBrush(QColor(0, 0, 255, 20)));

    curveAverage->setData(x_average, y_average);
    curveAverage->setPen(QPen(Qt::red));

//    customPlot->setupFullAxesBox();
    customPlot->rescaleAxes();
    customPlot->replot();
    curve->clearData();
    curveAverage->clearData();
}
/**
  * Load files of reference curves
  */
void Airfoil_dialog::load_reference_curve(QString path, QVector<Point *> &output)
{
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        std::cout << "Cannot find file(AirfoilDialog: load_reference_curve): " << path.toStdString() <<std::endl;
        file.close();
    }

    QTextStream in(&file);
    while(!in.atEnd())
    {
        QString line = in.readLine();
        QStringList line_list = line.split(" ", QString::SkipEmptyParts);

        if(line_list.size() == 2)
        {
            double x = line_list.at(0).toDouble();
            double y = line_list.at(1).toDouble();
            output.push_back(new Point(x, y));
        }
    }

    file.close();
}


void Airfoil_dialog::on_search_field_line_textChanged(const QString &arg1)
{
    ui->listFiles->keyboardSearch(arg1);
}

void Airfoil_dialog::on_listFiles_activated(const QModelIndex &index)
{
    QString pathFile = dirModel->fileInfo(index).absoluteFilePath();
    drawAirfoil(ui->customPlot, pathFile);

}

/**
  * Actions to do when the OK button is pressed
  */
void Airfoil_dialog::on_aceptar_button_pressed()
{
    QModelIndex modelIndex = ui->listFiles->currentIndex();
    QString  file_name = dirModel->fileName(modelIndex);

    std::cout << this->parent()->objectName().toStdString() << std::endl;

    Param_widget_uav *param_widget_uav;
    Param_widget_conventional *param_conventional;

    param_widget_uav = dynamic_cast<Param_widget_uav*> (this->parent());
    if(!param_widget_uav){
        param_conventional = dynamic_cast<Param_widget_conventional*> (this->parent());
        int call_id_button = param_conventional->last_button_pressed;
        param_conventional->load_airfoil_value(reference_curve, file_name, call_id_button);
    }
    else{
        int call_id_button = param_widget_uav->last_button_pressed;
        param_widget_uav->load_airfoil_value(reference_curve, file_name, call_id_button);
    }
    this->close();
}

/**
  * Actions to do when the Cancel button is pressed
  */
void Airfoil_dialog::on_cancelar_button_pressed()
{
    this->close();
}

/**
  * Set text in the widget.
  */
void Airfoil_dialog::retranslateUi(){
    setWindowTitle(tr("Airfoils"));
    ui->retranslateUi(this);
}
